package org.kongqian.car.service.impl;

import org.kongqian.basic.common.LoginContext;
import org.kongqian.basic.utils.AjaxResult;
import org.kongqian.basic.utils.VelocityUtils;
import org.kongqian.car.domain.Car;
import org.kongqian.car.domain.CarDetail;
import org.kongqian.car.domain.CarOnlineAuditLog;
import org.kongqian.car.domain.CarType;
import org.kongqian.car.es.doc.CarDoc;
import org.kongqian.car.es.repository.CarDocRepository;
import org.kongqian.car.mapper.CarDetailMapper;
import org.kongqian.car.mapper.CarMapper;
import org.kongqian.car.mapper.CarOnlineAuditLogMapper;
import org.kongqian.car.mapper.CarResourcesMapper;
import org.kongqian.car.service.ICarService;
import org.kongqian.basic.service.impl.BaseServiceImpl;
import org.kongqian.org.domain.Employee;
import org.kongqian.org.domain.Shop;
import org.kongqian.org.service.IBaiduAuditService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author kq
 * @since 2022-11-03
 */
@Service
public class CarServiceImpl extends BaseServiceImpl<Car> implements ICarService {

    @Value("${templates.velocity}")
    private String templatePath; //模板文件的路径

    @Value("${templates.generate}")
    private String generatePath; //静态文件生成后的路径

    @Value("${templates.delete}")
    private String deletePath; //下架后删除的静态文件详情路径

    @Autowired
    private IBaiduAuditService baiduAuditService;

    @Autowired
    private CarResourcesMapper carResourcesMapper;

    @Autowired
    private CarDetailMapper carDetailMapper;

    @Autowired
    private CarOnlineAuditLogMapper carOnlineAuditLogMapper;

    @Autowired
    private CarMapper carMapper;

    @Autowired
    private CarDocRepository carDocRepository;

    @Override
    @Transactional
    public void deleteById(Serializable id) {
        super.deleteById(id);

        //删除车辆详情
        carDetailMapper.deleteByCarId(id);

        //删除资源图片
        carResourcesMapper.deleteByCarId(id);
    }

    @Override
    @Transactional
    public void insert(Car car) {
        CarOnlineAuditLog log = new CarOnlineAuditLog();
        ////2.审核车辆信息 车辆名称 封面 基本信息
        String text=car.getTitle()+" "+car.getCarDetail().getInfo();
        String img=car.getCover();
        AjaxResult ajaxResult = baiduAuditService.baiduAudit(text, img, null);
        if (ajaxResult.getSuccess()){
            //进入这里说明审核通过
            //添加审核日志并保存
            //修改状态 1是通过 2是驳回
            log.setState(1);
            log.setAuditTime(new Date());
            log.setNote("自动审核通过");
        }else {
            //进入这里说明审核不通过
            log.setState(2);
            log.setAuditTime(new Date());
            log.setNote("自动审核不通过:"+ajaxResult.getMessage());
        }
        //1.保存car的信息
        car.setCreatetime(new Date());//创建时间
        car.setState(0);//状态：0下架 1上架
        car.setAuditstate(log.getState());//状态：0带审核 1审核通过 2驳回

        //设置店铺信息
        Employee loginAdmin = LoginContext.getLoginAdmin();
        car.setShopId(loginAdmin.getShop().getId());
        car.setShopname(loginAdmin.getShop().getName());
        //设置销售人员信息
        car.setSellerId(loginAdmin.getId());
        super.insert(car);

        //3.保存审核日志
        log.setCarId(car.getId());
        carOnlineAuditLogMapper.insert(log);

        //设置车辆详情
        CarDetail carDetail = car.getCarDetail();
        carDetail.setCarId(car.getId());
        carDetail.setCartitle(car.getTitle());
        carDetail.setInfo(car.getCarDetail().getInfo());
        carDetailMapper.insert(carDetail);

        //2.审核车辆信息
        //修改车辆信息状态
        //新增审核日志
    }

    @Override
    @Transactional
    public void updateById(Car car) {
        CarOnlineAuditLog log = new CarOnlineAuditLog();
        ////2.审核车辆信息 车辆名称 封面 基本信息
        String text=car.getTitle()+" "+car.getCarDetail().getInfo();
        String img=car.getCover();
        AjaxResult ajaxResult = baiduAuditService.baiduAudit(text, img, null);
        if (ajaxResult.getSuccess()){
            //进入这里说明审核通过
            //添加审核日志并保存
            //修改状态 1是通过 2是驳回
            log.setState(1);
            log.setAuditTime(new Date());
            log.setNote("自动审核通过");
        }else {
            //进入这里说明审核不通过
            log.setState(2);
            log.setAuditTime(new Date());
            log.setNote("自动审核不通过:"+ajaxResult.getMessage());
        }
        //1.保存car的信息
        car.setCreatetime(new Date());//创建时间
        car.setState(0);//状态：0下架 1上架
        car.setAuditstate(log.getState());//状态：0带审核 1审核通过 2驳回

        //设置店铺信息
        Employee loginAdmin = LoginContext.getLoginAdmin();
        car.setShopId(loginAdmin.getShop().getId());
        car.setShopname(loginAdmin.getShop().getName());
        //设置销售人员信息
        car.setSellerId(loginAdmin.getId());
        super.updateById(car);

        //3.保存审核日志
        log.setCarId(car.getId());
        carOnlineAuditLogMapper.insert(log);

        //设置车辆详情
        CarDetail carDetail = car.getCarDetail();
        carDetail.setCarId(car.getId());
        carDetail.setCartitle(car.getTitle());
        carDetail.setInfo(car.getCarDetail().getInfo());
        carDetailMapper.updateByCarId(carDetail);

        //2.审核车辆信息
        //修改车辆信息状态
        //新增审核日志

    }

    @Override
    @Transactional
    public void handleShelves(List<Long> ids) {
        //修改数据库的上架状态和上架时间  审核通过才能上架
            //参数校验
        if (ids==null || ids.size()<1){
            throw new RuntimeException("选择的数据不能小于1!");
        }
           //前端选择的ids长度 和数据库中查找出审核通过的个数相比较，如果不相等就返回错误信息，选择了没有审核通过的数据
        int authCount=carMapper.selectAuthCount(ids);
        if (authCount!=ids.size()){
            throw new RuntimeException("选择了没有审核通过的数据!");
        }
        //保存到es
        //方案一：一个ids一次查询对应的4张表，n次的话对数据库的操作次数为4n
        //方案二：为了减少对数据库的操作次数，用一条sql语句解决
        List<CarDoc> docs= getDocs(ids);
        carDocRepository.saveAll(docs);

        //修改数据库的上架状态和上架时间
        carMapper.handleShelves(ids);

        //添加上架日志 一条数据对应一条记录
        commonLog(ids,3);

        //上架的时候添加详情页面
        //上架几个我们就生成几个静态文件
        for (Long id : ids) {
            //生成静态页面需要三个参数，数据对象、模板文件磁盘路径、生成静态文件的磁盘路径
            Car car = carMapper.selectById(id); //数据对象
            //生成后的文件路径
            String generatePath=this.generatePath+"\\"+id+".html";
            VelocityUtils.staticByTemplate(car, templatePath,generatePath);
        }
    }

    private List<CarDoc> getDocs(List<Long> ids) {
        List<CarDoc> docs=new ArrayList<>();
        List<Car> cars = carMapper.getbatchDocByIds(ids);
        //遍历cars对象，一个一个的存在CarDoc集合中
        for (Car car : cars) {
            CarDoc carDoc = new CarDoc();
            //因为car和carDoc的属性是一样的，并且类型也是一样的，所以可以直接赋值
            BeanUtils.copyProperties(car, carDoc);
            //car里面的carType、shop carDetail的属性是对象，carDoc里的不是对象，所以要单独处理
            //carType设置
            CarType type = car.getType();
            //判断是否为空，为空就不赋值
            if (Objects.nonNull(type)){
                carDoc.setTypeId(type.getId());
                carDoc.setTypeName(type.getName());
            }

            //shop
            Shop shop = car.getShop();
            if (Objects.nonNull(shop)){
                carDoc.setShopId(shop.getId());
                carDoc.setShopAddress(shop.getAddress());
                carDoc.setShopName(shop.getName());
            }

            //carDetail
            CarDetail carDetail = car.getCarDetail();
            if (Objects.nonNull(carDetail)){
                carDoc.setCarInfo(carDetail.getInfo());
            }
            docs.add(carDoc);
        }
        return docs;
    }


    @Override
    @Transactional
    public void handleTakedown(List<Long> ids) {
        //修改数据库的上架状态和上架时间  审核通过才能上架
        //参数校验
        if (ids==null || ids.size()<1){
            throw new RuntimeException("选择的数据不能小于1!");
        }
        //删除es
        List<CarDoc> docs=new ArrayList<>();
        for (Long id : ids) {
            CarDoc carDoc = new CarDoc();
            carDoc.setId(id);
            docs.add(carDoc);
        }
        carDocRepository.deleteAll(docs);

        //修改数据库的下架状态和时间
        carMapper.handleTakedown(ids);

        //添加上架日志 一条数据对应一条记录
        commonLog(ids,4);

        //下架删除车辆详情静态文件
        for (Long id : ids) {
            File file = new File(deletePath+id+".html");
            file.delete();
        }
    }

    private void commonLog(List<Long> ids,Integer state) {
        String note=state==3 ? "上架":"下架";
        List<CarOnlineAuditLog> logs=new ArrayList<>();
        Employee loginAdmin = LoginContext.getLoginAdmin();
        for (Long id : ids) {
            CarOnlineAuditLog log = new CarOnlineAuditLog();
            log.setState(1);
            log.setCarId(id);
            log.setNote(loginAdmin.getUsername()+"对:"+id+"进行了"+note);
            log.setAuditTime(new Date());
            log.setAuditId(loginAdmin.getId());
            logs.add(log);
        }

        //添加上架和下架操作日志
        carOnlineAuditLogMapper.batchAddLog(logs);
    }
}
